#include "widget.h"
#include "./ui_widget.h"
// find_package(Qt6 COMPONENTS Core Network REQUIRED)  # Qt6 版本
// target_link_libraries(TCP_UDP PRIVATE Qt6::Network)
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    ui->leIp->setText("127.0.0.1");
    ui->sbPort->setValue(9999);
}

Widget::~Widget()
{
    qDebug() << "~Widget() start...";
    // 断开所有信号槽
    // if (tcpSocket) {
    //     tcpSocket->disconnect();  // 断开所有连接
    //     tcpSocket->abort();      // 强制关闭连接
    //     tcpSocket->deleteLater();
    //     tcpSocket = nullptr;
    // }
    delete ui;
    qDebug() << "~Widget() end...";
}

QString getCleanIp(const QHostAddress &address);

void Widget::on_pushButton_clicked()
{
    QString ip = ui->leIp->text();
    int port = ui->sbPort->value();
    TAB_TYPE tabType = (TAB_TYPE)ui->tabWidget->currentIndex();
    qDebug() << tabType;
    switch (tabType) {
        // case TCP_SERVER: {
        //     tcpServer = new QTcpServer;
        //     // 监听端口
        //     if (!tcpServer->listen(QHostAddress::Any, port)) {
        //         ui->teTcpServer->append("Server could not start:" + tcpServer->errorString());
        //         qDebug() << "Server could not start:" << tcpServer->errorString();
        //     } else {
        //         ui->teTcpServer->append("Server started on port" + QString(" %1").arg(tcpServer->serverPort()));
        //         qDebug() << "Server started on port" << tcpServer->serverPort();
        //     }
        //     connect(tcpServer, &QTcpServer::newConnection, this, [ = ]() {
        //         while (tcpServer->hasPendingConnections()) {
        //             QTcpSocket* clientTcpSocket = tcpServer->nextPendingConnection();
        //             QString key = QString("%1:%2").arg(getCleanIp(clientTcpSocket->peerAddress())).arg(clientTcpSocket->peerPort());
        //             clientTcpSocketMap[key] = clientTcpSocket;
        //             QString str = QString("%1:%2: \n").arg(getCleanIp(clientTcpSocket->peerAddress())).arg(clientTcpSocket->peerPort());
        //             ui->teTcpServer->append(str + "新的客户端进来了。。。");
        //             // 连接数据接收信号
        //             connect(clientTcpSocket, &QTcpSocket::readyRead, this, [ = ]() {
        //                 QByteArray data = clientTcpSocket->readAll();
        //                 QString str = QString("%1:%2: \n").arg(getCleanIp(clientTcpSocket->peerAddress())).arg(clientTcpSocket->peerPort());
        //                 ui->teTcpServer->append(str + data);
        //                 qDebug() << "Received:" << data;
        //                 qDebug() << "Received:" << clientTcpSocket->peerAddress().toString();
        //                 qDebug() << "Received:" << clientTcpSocket->peerPort();
        //                 // 回复客户端
        //                 // clientTcpSocket->write("Message received");
        //             });
        //             // 连接断开信号
        //             // connect(clientTcpSocket, &QTcpSocket::disconnected,
        //             //         clientTcpSocket, &QTcpSocket::deleteLater);
        //             connect(clientTcpSocket, &QTcpSocket::disconnected,
        //             this, [ = ]() {
        //                 clientTcpSocket->deleteLater();
        //                 clientTcpSocketMap.remove(key);
        //                 qDebug() << "tcp server  socket  connect close";
        //             });
        //         }
        //     });
        //     connect(tcpServer, &QTcpServer::destroyed, this, [ = ] {
        //         qDebug() << "Server socket destroyed";
        //         ui->teTcpServer->append("Server socket destroyed");
        //     });
        //     break;
        // }
        case TCP_SERVER: {
            tcpServer = new TcpServer(this, new QTcpServer, port);
            connect(tcpServer, &TcpServer::custom_readyRead, this, &Widget::do_TcpServerRecvMessage);
            connect(tcpServer, &TcpServer::listenSuccess, this, &Widget::do_listenSuccess);
            connect(tcpServer, &TcpServer::listenFailed, this, &Widget::do_listenFailed);
            connect(this, &Widget::do_write, tcpServer, &TcpServer::do_write);
            tcpServer->start();
            break;
        }
        case TCP_CLIENT: {
            if(ip.isEmpty()) {
                qDebug() << "ip is empty";
            }
            // 创建 TCP 套接字
            tcpSocket = new QTcpSocket(this) ;
            // 连接信号
            connect(tcpSocket, &QTcpSocket::connected, this, [ = ]() {
                qDebug() << "Connected to server";
                ui->teTcpClient->append("Connected to server");
                tcpSocket->write("Hello Server!");
            });
            connect(tcpSocket, &QTcpSocket::readyRead, this, [ = ]() {
                QByteArray data = tcpSocket->readAll();
                QString str = QString("%1:%2:").arg(tcpSocket->peerAddress().toString()).arg(tcpSocket->peerPort());
                ui->teTcpClient->append("<p style='color:green;'>" + str + "</p>"  );
                ui->teTcpClient->append(QString("  %1%2%3").arg("<p style='background-color: #1e9a5c; padding: 5px;'>").arg(data).arg( "</p>"));
                qDebug() << "Received:" << data;
                qDebug() << "Received:" << tcpSocket->peerAddress().toString();
                qDebug() << "Received:" << tcpSocket->peerPort();
            });
            connect(tcpSocket, &QTcpSocket::errorOccurred, this, [ = ](QAbstractSocket::SocketError error) {
                qDebug() << "Socket error:" << error << tcpSocket->errorString();
                tcpSocket->deleteLater();
            });
            connect(tcpSocket, &QTcpSocket::disconnected, this, [ = ]() {
                qDebug() << "Disconnected from server";
                // 关闭程序时，会先关闭当前widget，然后走到这里，如下日志可见，当此时再显示ui数据时回崩溃
                // ~Widget()...
                // Disconnected from server
                // ui->teTcpClient->append("Disconnected from server");
                // todo 这里需要优化，程序关闭时这里会崩溃，因为程序关闭时，ui组件已经销毁了
                // if(ui && ui->teTcpClient) {
                qDebug() << "ui->teTcpClient->append...";
                // ui->teTcpClient->append("Disconnected from server");
                // }
                qDebug() << "客户端程序断开连接......";
                qDebug() << tcpSocket  ;
                qDebug() << tcpSocket->state();
                tcpSocket->deleteLater();
                tcpSocket = nullptr; // 防止后续误用
                qDebug() << "客户端程序断开连接";
            });
            // 连接服务器
            tcpSocket->connectToHost(ip, port);
            break;
        }
        case UDP_SERVER: {
            udpServerSocket = new QUdpSocket(this);
            if(udpServerSocket->bind(port)) {
                qDebug() << "udp server bind port success";
            } else {
                qFatal() << "udp server bind port failed...";
            }
            connect(udpServerSocket, &QUdpSocket::readyRead, this, [ & ]() {
                while (udpServerSocket->hasPendingDatagrams()) {
                    QByteArray datagram;
                    datagram.resize(udpServerSocket->pendingDatagramSize());
                    QHostAddress senderAddress;  // 用于存储发送方IP
                    quint16 senderPort;         // 用于存储发送方端口
                    qint64 bytesRead = udpServerSocket->readDatagram(
                                           datagram.data(),
                                           datagram.size(),
                                           &senderAddress,
                                           &senderPort
                                       );
                    if (bytesRead != -1) {
                        qDebug() << "Received from:"
                                 << senderAddress.toString()
                                 << ":"
                                 << senderPort
                                 << "Data:"
                                 << datagram;
                        ui->teUdpServer->append("<p style='color:green;'>" + QString("%1:%2").arg(getCleanIp(senderAddress)).arg(senderPort) + "</p>"  );
                        ui->teUdpServer->append(QString("  %1%2%3").arg("<p style='background-color: yellow; padding: 5px;'>").arg(datagram).arg( "</p>"));
                    }
                }
                // ui->teUdpServer->append("udp server received msg...");
            });
            connect(udpServerSocket, &QUdpSocket::disconnected, this, [ = ]() {
                // 如果没有connect 某个服务器端口的话，就不会有断开链接操作
                qDebug() << "disconnected...";
            });
            connect(udpServerSocket, &QUdpSocket::disconnected, udpServerSocket, &QUdpSocket::deleteLater);
            break;
        }
        case UDP_CLIENT: {
            qDebug() << "udpClientSocket...";
            udpClientSocket = new QUdpSocket(this);
            // 绑定广播地址
            if(!udpClientSocket->bind(1234, QUdpSocket::ShareAddress)) {
                qDebug() << "绑定端口失败：" << udpClientSocket->errorString();
                return;
            }
            connect(udpClientSocket, &QUdpSocket::readyRead, this, [ & ]() {
                while (udpClientSocket->hasPendingDatagrams()) {
                    QByteArray datagram;
                    datagram.resize(udpClientSocket->pendingDatagramSize());
                    QHostAddress senderAddress;
                    quint16 senderPort;
                    udpClientSocket->readDatagram(datagram.data(), datagram.size(), &senderAddress, &senderPort);
                    qDebug() << "收到广播来自：" << senderAddress.toString()
                             << ":" << senderPort
                             << "内容：" << datagram;
                    ui->teUdpClient->append("<p style='color:green;'>" + QString("%1:%2:%3").arg("收到广播来自 ").arg(getCleanIp(senderAddress)).arg(senderPort) + "</p>"  );
                    ui->teUdpClient->append(QString("  %1%2%3").arg("<p style='background-color: yellow; padding: 5px;'>").arg(datagram).arg( "</p>"));
                }
            });
            connect(udpClientSocket, &QUdpSocket::disconnected, this, [ = ]() {
                // 如果没有connect 某个服务器端口的话，就不会有断开链接操作
                qDebug() << "disconnected...";
            });
            connect(udpClientSocket, &QUdpSocket::disconnected, udpClientSocket, &QUdpSocket::deleteLater);
            udpClientSocket->writeDatagram(QString("hello server").toUtf8(), QHostAddress(ip), port);
            break;
        }
    }
}


void Widget::on_pushButton_2_clicked()
{
    QString ip = ui->leIp->text();
    int port = ui->sbPort->value();
    TAB_TYPE tabType = (TAB_TYPE)ui->tabWidget->currentIndex();
    switch (tabType) {
        // case TCP_SERVER: {
        //     // 1. 停止接受新连接
        //     tcpServer->pauseAccepting();
        //     // 2. 断开所有客户端连接
        //     // 3. 关闭服务器
        //     tcpServer->close();
        //     // 关闭时检查错误
        //     // if (!tcpServer->close()) {
        //     //     qWarning() << "Failed to close server properly:"
        //     //                << tcpServer->errorString();
        //     //     // 强制关闭
        //     //     tcpServer->deleteLater();
        //     // }
        //     tcpServer->deleteLater();
        //     // 4. 清理资源
        //     qDebug() << "Server stopped successfully";
        //     break;
        // }
        case TCP_SERVER: {
            tcpServer->stop();
            break;
        }
        case TCP_CLIENT: {
            tcpSocket->close();
            qDebug() << "client stopped successfully";
            break;
        }
        case UDP_SERVER: {
            udpServerSocket->close();
            qDebug() << "client stopped successfully";
            break;
        }
        case UDP_CLIENT: {
            udpClientSocket->close();
            qDebug() << "client stopped successfully";
            break;
        }
    }
}

void Widget::do_TcpServerRecvMessage(QString source, QByteArray &data)
{
    // ui->teTcpServer->append(source + ":\n  " + data);
    ui->teTcpServer->append("<p style='color:green;'>" + source + "</p>"  );
    ui->teTcpServer->append(QString("  %1%2%3").arg("<p style='background-color: yellow; padding: 5px;'>").arg(data).arg( "</p>"));
}


void Widget::on_pushButton_3_clicked()
{
    QString ip = ui->leIp->text();
    int port = ui->sbPort->value();
    QString msg = ui->teSendMessage->toPlainText();
    TAB_TYPE tabType = (TAB_TYPE)ui->tabWidget->currentIndex();
    switch (tabType) {
        // case TCP_SERVER: {
        //     // 使用迭代器
        //     for (auto it = clientTcpSocketMap.begin(); it != clientTcpSocketMap.end(); ++it) {
        //         if(it.value()->state() == QAbstractSocket::ConnectedState) {
        //             it.value()->write( msg.toUtf8());
        //         } else {
        //             qWarning() << "Cannot send data - socket not connected";
        //         }
        //     }
        //     break;
        // }
        case TCP_SERVER: {
            // ui->teTcpServer->setStyleSheet("");  // 清除样式表
            ui->teTcpServer->append("<p style='color:red;'>自己:</p>"  );
            ui->teTcpServer->append(QString("  %1%2%3").arg("<p style='background-color: #90cbfb; padding: 5px;'>").arg(msg).arg( "</p>"));
            emit do_write(msg);
            break;
        }
        case TCP_CLIENT: {
            if(tcpSocket->state() ==  QAbstractSocket::ConnectedState) {
                ui->teTcpClient->append("<p style='color:red;'>自己:</p>"  );
                ui->teTcpClient->append(QString("  %1%2%3").arg("<p style='background-color: #90cbfb; padding: 5px;'>").arg(msg).arg( "</p>"));
                tcpSocket->write( msg.toUtf8());
            } else {
                qWarning() << "Cannot send data - socket not connected";
            }
            break;
        }
        case UDP_SERVER: {
            //todo 这里暂时不处理，应该是服务端收集所有的客户端ip信息，端口信息，然后调用writeDatagram(msg.toUtf8(), QHostAddress(ip), port ); 发送消息
            qDebug() << "send msg to all clients...";
            // 发送广播数据
            ui->teUdpServer->append("<p style='color:red;'>自己:</p>"  );
            ui->teUdpServer->append(QString("  %1%2%3").arg("<p style='background-color: #90cbfb; padding: 5px;'>").arg(msg).arg( "</p>"));
            udpServerSocket->writeDatagram(msg.toUtf8(), QHostAddress::Broadcast, 1234 );
            break;
        }
        case UDP_CLIENT: {
            ui->teUdpClient->append("<p style='color:red;'>自己:</p>"  );
            ui->teUdpClient->append(QString("  %1%2%3").arg("<p style='background-color: #90cbfb; padding: 5px;'>").arg(msg).arg( "</p>"));
            udpClientSocket->writeDatagram(msg.toUtf8(), QHostAddress(ip), port );
            break;
        }
    }
    ui->teSendMessage->clear();
}

void Widget::do_listenSuccess(int port)
{
    qDebug() << "do_listenSuccess...";
    ui->teTcpServer->append("Server started on port" + QString(" %1").arg(port));
}

void Widget::do_listenFailed(QString errMsg)
{
    qDebug() << "do_listenFailed...";
    ui->teTcpServer->append("Server could not start:" + errMsg);
}

QString getCleanIp(const QHostAddress &address)
{
    QString ip = address.toString();
    // 移除IPv6的方括号(如果有)
    ip.remove('[');
    ip.remove(']');
    // 转换IPv4映射的IPv6地址
    if(ip.startsWith("::ffff:")) {
        ip = ip.mid(7);
    }
    return ip;
}
